Procedure Definitions
/* params = lat1, lon1, lat2, lon2, return = distance */
CREATE OR REPLACE FUNCTION LatLonDistance( float8, float8, float8, float8 ) RETURNS float8
AS 'SELECT SQRT(POW((69.1*($2-$4)*COS($3/57.3)),2)+POW((69.1*($1-$3)),2));
' LANGUAGE 'sql' RETURNS NULL ON NULL INPUT;
/* params = zip1, zip2, return = distance */
CREATE OR REPLACE FUNCTION ZipDistance( int4, int4 ) RETURNS float8
AS 'SELECT LatLonDistance( zd.lat, zd.lon,zd2.lat,zd2.lon )
FROM zipdata zd, zipdata zd2
WHERE zd.zipcode = $1
and zd2.zipcode = $2;
' LANGUAGE 'sql' RETURNS NULL ON NULL INPUT;
Usage
This is just as versitile, but much cleaner than te quries last night:
a. Getting the distance between two users:
SELECT u.username, u2.username, ZipDistance( u.zipcode, u2.zipcode ) AS distance
FROM users u, users u2
WHERE u.username='harlan' AND u2.username='zack';
b. Getting all users within 10 miles of a zipcode (55431):
SELECT u.username
FROM users u
WHERE ZipDistance( 55431, u.zipcode ) <>